package cn.xiazhi.charging.order.mqtt;

import cn.xiazhi.charging.common.ChargingConstant;
import cn.xiazhi.charging.common.MqttConstant;
import cn.xiazhi.charging.order.common.OrderStatusConstant;
import cn.xiazhi.charging.order.pojo.dto.ChargingResultDto;
import cn.xiazhi.charging.order.pojo.po.ChargingBillFailPO;
import cn.xiazhi.charging.order.pojo.po.ChargingBillSuccessPO;
import cn.xiazhi.charging.utils.JsonUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;

@Slf4j
@Data
public class MqttConsumer implements MqttCallbackExtended {

    /**
     * 通过写方法 setter 设置 mqttClient
     * @param mqttClient
     */
    private MqttClient mqttClient;
    private MqttContext mqttContext;

    /**
     * 连接EMQX 成功后,订阅Topic
     * @param reconnect If true, the connection was the result of automatic reconnect.
     * @param serverURI The server URI that the connection was made to.
     */
    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
        log.debug("mqtt连接成功后条用connectComplete,reconnect: {}, serverURI: {}",reconnect,serverURI);
        //connect mqttClient的连接方法,基于配置 connOpts 和 EMQX 进行连接
        try {
            mqttClient.subscribe(MqttConstant.TOPIC_CHARGING_RESULT);
        } catch (MqttException e) {
            log.error("mqtt.subscribe订阅失败,error: {}",e.getMessage());
        }
        log.debug("成功订阅开始充电指令结果 topic:{},",MqttConstant.TOPIC_CHARGING_RESULT);
    }

    @Override
    public void connectionLost(Throwable throwable) {

    }

    /**
     * messageArrived 指的是 设备发送的消息 到达了 订单服务
     *  设备发送的指令  --->EMQX ---> 订单服务
     * @param topic name of the topic on the message was published to
     * @param message the actual message.
     * @throws Exception
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        log.debug("MqttConsumer#messageArrived方法被调用了,表示消息到达,topic:{},message:{}",topic,message);
        ChargingResultDto chargingResultDto = null;
        //把设备发送的消息JSON转换为java对象 chargingResultDto
        try {
            chargingResultDto = JsonUtil.fromJson(message.toString(),ChargingResultDto.class);
            if (chargingResultDto != null){
                //获取开始充电指令设备给的返回响应 开始充电成功/开始充电失败
                String result = chargingResultDto.getResult();
                //判断设备响应结果
                if (ChargingConstant.RESULT_START_CHARGING_SUCCESS.equals(result)){
                    log.debug("设备有响应,设备开始充电成功");

                    ChargingBillSuccessPO chargingBillSuccessPO = new ChargingBillSuccessPO();
                    chargingBillSuccessPO.setBillId(chargingResultDto.getOrderNo());
                    chargingBillSuccessPO.setBillStatus(OrderStatusConstant.ORDER_STATUS_PROCESS);
                    log.debug("保存成功订单记录:{}",chargingBillSuccessPO);
                    Integer row = mqttContext.getOrderSuccessMapper().insert(chargingBillSuccessPO);
                    log.debug("保存成功订单记录:{},影响行数:{}",chargingBillSuccessPO,row);
                }else {
                    log.debug("设备有响应,设备开始充电失败");

                    ChargingBillFailPO chargingBillFailPO = new ChargingBillFailPO();
                    chargingBillFailPO.setBillId(chargingResultDto.getOrderNo());
                    chargingBillFailPO.setFailDesc("设备有响应,开始充电失败");
                    log.debug("保存失败订单记录:{}",chargingBillFailPO);
                    Integer row = mqttContext.getOrderFailMapper().insert(chargingBillFailPO);

                    log.debug("保存失败订单记录:{},影响行数:{}",chargingBillFailPO,row);
                    log.debug("通知充电的用户,表示歉意,提醒用户更换充电枪");
                    log.debug("通知设备管理员,进行设备的检修");
                }
            }
        } catch (Exception e) {
            log.error("设备发送的开始充电结果消息{},格式有问题,请检查!,error: {}",message,e.getMessage());
        }

    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

    }
}
